﻿using System;
using System.Collections.ObjectModel;
using System.Composition;
using System.Threading.Tasks;
using System.Windows.Input;
using Unread.App.Common;
using Unread.App.Services.Interfaces;
using Unread.App.Views;
using Unread.Business.Models;
using Unread.Business.Repositories.Interfaces;
using Unread.Business.Services.Interfaces;

namespace Unread.App.ViewModels
{
    [Export]
    public class ManageFeedsViewModel : BindableBase
    {
        private const string DefaultFeedImage = "";

        private readonly IFeedRepository _feedRepository;
        private readonly INavigationService _navigationService;
        private readonly IFeedRemover _feedRemover;

        private bool _isLoading;
        public bool IsLoading
        {
            get { return _isLoading; }
            set { SetProperty(ref _isLoading, value); }
        }

        private FeedViewModel _selectedFeed;
        public FeedViewModel SelectedFeed
        {
            get { return _selectedFeed; }
            set { SetProperty(ref _selectedFeed, value); }
        }

        public ObservableCollection<FeedViewModel> Feeds { get; set; }

        [ImportingConstructor]
        public ManageFeedsViewModel(IFeedRepository feedRepository, INavigationService navigationService, IFeedRemover feedRemover)
        {
            if (feedRepository == null) throw new ArgumentNullException("feedRepository");
            if (navigationService == null) throw new ArgumentNullException("navigationService");
            if (feedRemover == null) throw new ArgumentNullException("feedRemover");

            _feedRepository = feedRepository;
            _navigationService = navigationService;
            _feedRemover = feedRemover;

            Feeds = new ObservableCollection<FeedViewModel>();

            OpenFeedCommand = new DelegateCommand(OpenFeed, CanOpenFeed);
            AddFeedCommand = new DelegateCommand(AddFeed, CanAddFeed);
            RemoveFeedCommand = new DelegateCommand(RemoveFeed, CanRemoveFeed);
            HomeCommand = new DelegateCommand(GoHome);
        }

        public async Task Load()
        {
            IsLoading = true;
            Feeds.Clear();

            var allFeeds = await _feedRepository.GetAll();

            foreach (var feed in allFeeds)
            {
                Feeds.Add(new FeedViewModel 
                { 
                    Id = feed.Id,
                    Title = feed.Title,
                    Subtitle = feed.Subtitle,
                    Image = (feed.Image != null ? feed.Image.AbsoluteUri : DefaultFeedImage)
                });
            }

            IsLoading = false;
        }

        #region OpenFeedCommand

        public ICommand OpenFeedCommand { get; set; }

        private bool CanOpenFeed(object arg)
        {
            return (SelectedFeed != null);
        }

        private void OpenFeed(object obj)
        {
            var navParams = new FeedItemIdentifier { FeedId = SelectedFeed.Id, FeedItemUri = null };

            _navigationService.Navigate(typeof(FeedItemPage), navParams);
        }

        #endregion

        #region AddFeedCommand

        public ICommand AddFeedCommand { get; set; }

        private bool CanAddFeed(object arg)
        {
            return true;
        }

        private void AddFeed(object obj)
        {
            _navigationService.Navigate(typeof(AddFeedPage));
        }

        #endregion

        #region RemoveFeedCommand

        public ICommand RemoveFeedCommand { get; set; }

        private bool CanRemoveFeed(object arg)
        {
            return (SelectedFeed != null);
        }

        private async void RemoveFeed(object obj)
        {
            await _feedRemover.Remove(SelectedFeed.Id);
            SelectedFeed = null;

            await Load();
        }

        #endregion

        #region HomeCommand

        public ICommand HomeCommand { get; set; }

        private void GoHome(object obj)
        {
            _navigationService.Navigate(typeof(UnreadPage));
        }

        #endregion
    }
}